package com.mmall.service;

import com.google.common.base.Preconditions;
import com.mmall.common.ExceptionError;
import com.mmall.common.RequestHolder;
import com.mmall.dao.SysAclModuleMapper;
import com.mmall.model.SysAclModule;
import com.mmall.param.AclModuleParam;
import com.mmall.util.BeanVaildator;
import com.mmall.util.IpUtil;
import com.mmall.util.LevelUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class SysAclModuleService {
    @Resource
    private SysAclModuleMapper mapper;
    @Resource
    private SysLogService sysLogService;

    public void save(AclModuleParam param) {
        BeanVaildator.check(param);
        if (checkNameExist(param.getId(), param.getName(), param.getParentId())) {
            ExceptionError.throwError("同一层级下存在相同名称的权限模块");
        }
        SysAclModule aclModule = SysAclModule.builder().name(param.getName())
                .parentId(param.getParentId())
                .remark(param.getRemark())
                .seq(param.getSeq())
                .status(param.getStatus())
                .operateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()))
                .operator(RequestHolder.getCurrentUser().getUsername())
                .operateTime(new Date())
                .level(LevelUtil.calculateLevel(getLevel(param.getParentId()), param.getParentId()))
                .build();

        mapper.insertSelective(aclModule);
        sysLogService.saveAclModuleLog(null,aclModule);

    }

    public void update(AclModuleParam param) {
        BeanVaildator.check(param);
        if (checkNameExist(param.getId(), param.getName(), param.getParentId())) {
            ExceptionError.throwError("同一层级下存在相同名称的权限模块");
        }
        SysAclModule before = mapper.selectByPrimaryKey(param.getId());
        Preconditions.checkNotNull(before, "待更新的权限模块不存在");

        SysAclModule after = SysAclModule.builder().id(param.getId()).name(param.getName())
                .parentId(param.getParentId())
                .remark(param.getRemark())
                .seq(param.getSeq())
                .status(param.getStatus())
                .operateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()))
                .operator(RequestHolder.getCurrentUser().getUsername())
                .operateTime(new Date())
                .level(LevelUtil.calculateLevel(getLevel(param.getParentId()), param.getParentId()))
                .build();
        updateWithChild(before, after);
        sysLogService.saveAclModuleLog(before,after);

    }

    /**
     * 更新子模块
     *
     * @param before
     * @param after
     */
    private void updateWithChild(SysAclModule before, SysAclModule after) {
        String newLevelPrefix = after.getLevel();
        String oldLevelPrefix = before.getLevel();

        if (!StringUtils.equals(newLevelPrefix, oldLevelPrefix)) {
            String childLevel = oldLevelPrefix + LevelUtil.SEPARATOR + after.getId();

            List<SysAclModule> aclModules = mapper.getChildAclModelListByLevel(childLevel);
            if (CollectionUtils.isNotEmpty(aclModules)) {

                for (SysAclModule aclModule : aclModules) {
                    String level = aclModule.getLevel();
                    if (level.indexOf(oldLevelPrefix) == 0) {
                        level = newLevelPrefix + level.substring(oldLevelPrefix.length());
                        aclModule.setLevel(level);
                    }
                }
                mapper.batchUpdateLevel(aclModules);
            }
        }
        mapper.updateByPrimaryKey(after);
    }

    public String getLevel(Integer id) {
        SysAclModule aclModule = mapper.selectByPrimaryKey(id);
        if (aclModule == null) {
            return null;
        }
        return aclModule.getLevel();
    }

    public boolean checkNameExist(Integer id, String name, Integer parentId) {
        return mapper.countByNameAndParentId(parentId, name, id) > 0;
    }

    public void delete(Integer id) {
        SysAclModule aclModule = mapper.selectByPrimaryKey(id);
        Preconditions.checkNotNull(aclModule, "待删除的权限模块不存在，无法删除");
        String childLevel = aclModule.getLevel() + LevelUtil.SEPARATOR + aclModule.getId();
        if (CollectionUtils.isNotEmpty(mapper.getChildAclModelListByLevel(childLevel))){
            ExceptionError.throwError("当前权限模块下面有子模块，无法删除");
        }
        mapper.deleteByPrimaryKey(id);
        sysLogService.saveAclModuleLog(aclModule,null);
    }
}
